# -*- coding: utf-8 -*-
from api import api, ERROR_PROBLEM, GlobalError
from flask import jsonify, request
from model.answer import Answer
from model.comment import Comment
from model.problem import Problem
from model.studio import Studio
from model.user import User
from werkzeug.exceptions import NotFound

from flask.ext.login import login_required

class Error:
    NO_USER_LOGINED = {
        'err': ERROR_PROBLEM + 1,
        'msg': 'Login is required'
    }


@api.route('/problem/<problem_id>', methods=['GET'])
def get_problem(problem_id):
    '''
## 用问题 ID 获取问题详情

    GET /api/problem/<problem_id>

Parameters:

* `userId` (optional) - 当前登录的用户 ID，可选

Return:

* `problem` (dict) - info of problem
    * `_id` (string) - 问题 ID
    * `avatarUrl` (string)
    * `name` (string)
    * `place` (dict)
        * `province` (string)
        * `city` (string)
    * `askTo` (string) - 被提问者的 ID
    * `askToName` (string) - 被提问者的名字
    * `askToAvatarUrl` (string) - 被提问者头像
    * `askToType` (int) - 被提问者身份，1表示教师，2表示画室
    * `content` (string) - 提问内容
    * `image` (string) - 图片链接
    * `answerList` (list of dict)
        * `_id` - 回答 ID
        * `content` (list of dict) - 回答内容列表
            * `aType` (int)
            * `content` (string)
        * `problemId` (string) - 问题 ID
        * `userId` (string) - 回答者 ID
        * `userName` (string) - 回答者名
        * `avatarUrl` (string) - 回答者头像
        * `uType` (int) - 回答者的身份，1表示教师，2表示画室
    * `commentList` (list of dict)
        * `_id` (string) - 评论 ID
        * `fromUserId` (string) - 评论人的 ID
        * `fromUerName` (string) - 评论人的名字
        * `fromUserAvatarUrl` (string) - 评论人的头像链接
        * `toUserId` (string)
        * `toUserName` (string)
        * `content` (string)
        * `timestamp` (long) - 时间戳
        * `problemId` (string)
    * `tag` (list of string) - 问题标签列表
    * `isZan` (int) - 1 表示当前用户点了赞，0表示没有点赞
    * `zan` (int) - 点赞数目
    * `viewNum` (int) - 点击数目
    * `commentNum` (int) - 评论数
    * `answerNum` (int) - 教师回答数
    * `timestamp` (long) - 时间戳
    * `userId` (string) - 提问者 ID

Errors: `2`
    '''

    try:
        problem = Problem.get({
            Problem.Field._id: problem_id
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_PROBLEM_ID)

    is_zan = 0
    user_id = request.args.get('userId', None)
    if user_id and problem.data.get(Problem.Field.zanList) \
            and problem.data.get(Problem.Field.zanList).get(user_id):
            is_zan = 1
    problem.data['isZan'] = is_zan

    answer_list = problem.data.get(Problem.Field.answerList)
    comment_list = problem.data.get(Problem.Field.commentList)
    problem.data[Problem.Field.answerList] = []
    problem.data[Problem.Field.commentList] = []

    student = User.get({
        User.Field._id: problem.data.get(Problem.Field.userId)
    })
    problem.data[User.Field.avatarUrl] = student.data.get(User.Field.avatarUrl, '')
    problem.data[User.Field.name] = student.data.get(User.Field.name, '')
    problem.data[User.Field.place] = student.data.get(User.Field.place, {
        User.Place.province: '',
        User.Place.city: ''
    })

    try:
        ask_to = User.get({
            User.Field._id: problem.data.get(Problem.Field.askTo)
        })
        problem.data['askToName'] = ask_to.data.get(User.Field.name)
        problem.data['askToAvatarUrl'] = ask_to.data.get(User.Field.avatarUrl)
        problem.data['askToType'] = 1
    except NotFound:
        try:
            ask_to = Studio.get({
                Studio.Field._id: problem.data.get(Problem.Field.askTo)
            })
            problem.data['askToName'] = ask_to.data.get(Studio.Field.name)
            problem.data['askToAvatarUrl'] = ask_to.data.get(Studio.Field.avatarUrl)
            problem.data['askToType'] = 2
        except NotFound:
            pass

    for answer_id in answer_list:
        try:
            answer = Answer.get({
                Answer.Field._id: answer_id
            })
            try:
                teacher = User.get({
                    User.Field._id: answer.data.get(Answer.Field.userId)
                })
                answer.data['userName'] = \
                    teacher.data.get(User.Field.name)
                answer.data['avatarUrl'] = \
                    teacher.data.get(User.Field.avatarUrl)
                answer.data['uType'] = 1
            except NotFound:
                try:
                    studio = Studio.get({
                        Studio.Field._id: answer.data.get(Answer.Field.userId)
                    })
                    answer.data['userName'] = \
                        studio.data.get(Studio.Field.name)
                    answer.data['avatarUrl'] = \
                        studio.data.get(Studio.Field.avatarUrl)
                    answer.data['uType'] = 2
                except NotFound:
                    continue
            problem.data[Problem.Field.answerList].append(answer.data)
        except NotFound:
            continue

    for comment_id in comment_list:
        try:
            comment = Comment.get({
                Comment.Field._id: comment_id
            })
            try:
                student = User.get({
                    User.Field._id: comment.data.get(Comment.Field.fromUserId)
                })
                comment.data['fromUserName'] = \
                    student.data.get(User.Field.name)
                comment.data['fromUserAvatarUrl'] = \
                    student.data.get(User.Field.avatarUrl)
            except NotFound:
                continue
            if comment.data.get(Comment.Field.toUserId):
                try:
                    student = User.get({
                        User.Field._id: comment.data.get(Comment.Field.toUserId)
                    })
                    comment.data['toUserName'] = \
                        student.data.get(User.Field.name)
                except:
                    comment.data['toUserName'] = ''
            problem.data[Problem.Field.commentList].append(comment.data)
        except NotFound:
            continue

    return jsonify(stat=1, problem=problem.data)


@api.route('/problem/<problem_id>/zan', methods=['PUT'])
def update_zan(problem_id):
    '''
## 点赞

    PUT /api/problem/<problem_id>/zan

Parameters:

* `userId` (string, required) - 当前登录的用户 ID
* `zan` (int, optional) - 1 表示点赞, -1 表示取消赞, 默认为 1

Errors: `5`, `4001`
    '''

    zan = request.form.get('zan', 1, type=int)
    if zan != 1 and zan != -1:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    user_id = request.form.get('userId', None)
    if user_id is None:
        return jsonify(stat=0, **Error.NO_USER_LOGINED), 403

    try:
        Problem.update_zan(problem_id, user_id, zan)
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_PROBLEM_ID), 403

    return jsonify(stat=1)


@api.route('/problem/<problem_id>/comments', methods=['GET'])
def get_problem_comments(problem_id):
    '''
## 分页获取问题下的评论

    GET /api/problem/<problem_id>/comments

Parameters:

* `skip` (int, optional) - 跳过多少个问题，默认为 0
* `total` (int, optional) - 返回多少个问题，默认为 10

Return:

* `comments` ([dict]) - 返回一个字典列表，每一个字典都是一个评论
    * `_id` (string) - 评论 ID
    * `fromUserId` (string) - 评论人的 ID
    * `fromUerName` (string) - 评论人的名字
    * `fromUserAvatarUrl` (string) - 评论人的头像链接
    * `toUserId` (string)
    * `toUserName` (string)
    * `content` (string)
    * `timestamp` (long) - 时间戳
    * `problemId` (string)
    '''
    skip = request.args.get('skip', 0, type=int)
    total = request.args.get('total', 10, type=int)


    comment_list = Comment.find({
        Comment.Field.problemId: problem_id
    }, [
        Comment.Field._id,
        Comment.Field.problemId,
        Comment.Field.fromUserId,
        Comment.Field.content,
        Comment.Field.toUserId,
        Comment.Field.timestamp
    ],
        sort=[(Problem.Field.timestamp, -1)],
        skip=skip,
        limit=total)

    comments = []
    for comment in comment_list:
        try:
            student = User.get({
                User.Field._id: comment.get(Comment.Field.fromUserId)
            })
            comment['fromUserName'] = student.data.get(User.Field.name)
            comment['fromUserAvatarUrl'] = student.data.get(User.Field.avatarUrl)
        except NotFound:
            continue
        if comment.get(Comment.Field.toUserId):
            try:
                student = User.get({
                    User.Field._id: comment.get(Comment.Field.toUserId)
                })
                comment['toUserName'] = student.data.get(User.Field.name)
            except:
                comment['toUserName'] = ''
        else:
            comment['toUserName'] = ''
        comments.append(comment)

    return jsonify(stat=1, comments=comments)


@api.route('/problem/<problem_id>/answers', methods=['GET'])
def get_problem_answers(problem_id):
    '''
## 用问题 ID 获取回答

    GET /api/problem/<problem_id>/answers

Return:

* `answers` (list of dict)
    * `_id` - 回答 ID
    * `content` (list of dict) - 回答内容列表
        * `aType` (int)
        * `content` (string)
    * `problemId` (string) - 问题 ID
    * `userId` (string) - 回答者 ID
    * `userName` (string) - 回答者名
    * `avatarUrl` (string) - 回答者头像
    * `uType` (int) - 回答者的身份，1表示教师，2表示画室

Errors: `2`
    '''

    try:
        problem = Problem.get({
            Problem.Field._id: problem_id
        }, [
            Problem.Field.answerList
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_PROBLEM_ID)

    answer_list = problem.data.get(Problem.Field.answerList)
    answers = []

    for answer_id in answer_list:
        try:
            answer = Answer.get({
                Answer.Field._id: answer_id
            })
            try:
                teacher = User.get({
                    User.Field._id: answer.data.get(Answer.Field.userId)
                })
                answer.data['userName'] = \
                    teacher.data.get(User.Field.name)
                answer.data['avatarUrl'] = \
                    teacher.data.get(User.Field.avatarUrl)
                answer.data['uType'] = 1
            except NotFound:
                try:
                    studio = Studio.get({
                        Studio.Field._id: answer.data.get(Answer.Field.userId)
                    })
                    answer.data['userName'] = \
                        studio.data.get(Studio.Field.name)
                    answer.data['avatarUrl'] = \
                        studio.data.get(Studio.Field.avatarUrl)
                    answer.data['uType'] = 2
                except NotFound:
                    continue
            answers.append(answer.data)
        except NotFound:
            continue

    return jsonify(stat=1, answers=answers)


@api.route('/problems', methods=['GET'])
# @login_required
def get_problem_list():
    '''
## 获取所有的问题，按照时间顺序

    GET /api/problems

Parameters:

* `skip` (int, optional) - 跳过多少个问题，默认为 0
* `total` (int, optional) - 返回多少个问题，默认为 10
* `timestamp` (long, optional) - 返回这个时间戳之前的问题
* `userId` (string, optional) - 当前登录的用户 ID，可选

Return:

* `problems` ([dict]) - 返回一个字典列表，每一个字典都是一个问题
    * `_id` (string)
    * `askTo` (string) - 被提问者的 ID
    * `askToName` (string) - 被提问者的名字
    * `askToAvatarUrl` (string) - 被提问者头像
    * `askToType` (int) - 被提问者身份，1表示教师，2表示画室
    * `commentNum` (int) - 评论数
    * `content`
    * `image` (string) - 图片的链接
    * `isZan` (int) - 1 表示当前用户点了赞，0表示没有点赞
    * `zan` (int)
    * `tag` (list of string) - 问题的标签列表
    * `viewNum` (int)
    * `answerNum` (int)
    * `timestamp` (long) - 时间戳
    * `userId` (string) - 提问者 ID
    * `name` (string) - 提问者昵称
    * `avatarUrl` (string) - 提问者头像链接
    '''

    skip = request.args.get('skip', 0, type=int)
    total = request.args.get('total', 10, type=int)
    timestamp = request.args.get('timestamp', -1, type=long)
    user_id = request.args.get('userId', None)

    #这是不行的，因为有人可以假冒id获取！！真正做好Login吧
    try:
        user = User.get({
            User.Field._id: user_id
            })
    except NotFound:
        return jsonify(stat=0, **Error.NO_USER_LOGINED)

    query_condition = {}
    if timestamp != -1:
        query_condition[Comment.Field.timestamp] = {'$lt': timestamp}
        skip = 0

# * `askMeList` ([string]) - ask me list of user (teacher only)
# * `askList` ([string]) - ask list of user (student only)
    problems = User.find({User.Field._id: user_id})
    myProblems = problems[0].get('askMeList', []) + problems[0].get('askList', [])
    follows = problems[0].get('follow', [])
    #print follows
    for follow in follows:
        problems = User.find({User.Field._id: follow})
        if problems:
            myProblems += problems[0].get('askList', [])
    myProblems = list(set(myProblems))  #去重
    query_condition[Problem.Field._id] = { '$in': myProblems }
    # print('haha', myProblems);
    # print('huhu', query_condition);
    problem_list = Problem.find(query_condition,
        [Problem.Field._id,
         Problem.Field.askTo,
         Problem.Field.commentNum,
         Problem.Field.content,
         Problem.Field.image,
         Problem.Field.zan,
         Problem.Field.tag,
         Problem.Field.viewNum,
         Problem.Field.answerNum,
         Problem.Field.timestamp,
         Problem.Field.userId,
         Problem.Field.zanList,
         Problem.Field.commentNum],
        sort=[(Problem.Field.timestamp, -1)],
        skip=skip,
        limit=total)

    problems = []

    for problem in problem_list:
        try:
            user = User.get({
                User.Field._id: problem.get(Problem.Field.userId)
            }, [
                User.Field.name,
                User.Field.avatarUrl
            ])
        except:
            continue

        is_zan = 0
        if user_id and problem.get(Problem.Field.zanList) \
                and problem.get(Problem.Field.zanList).get(user_id):
            is_zan = 1
        ask_to_name = ""
        ask_to_avatar_url = ""
        ask_to_type = -1

        try:
            ask_to = User.get({
                User.Field._id: problem.get(Problem.Field.askTo)
            }, [
                User.Field.name,
                User.Field.avatarUrl
            ])
            ask_to_name = ask_to.data.get(User.Field.name)
            ask_to_avatar_url = ask_to.data.get(User.Field.avatarUrl)
            ask_to_type = 1
        except NotFound:
            try:
                ask_to = Studio.get({
                    Studio.Field._id: problem.get(Problem.Field.askTo)
                }, [
                    Studio.Field.name,
                    Studio.Field.avatarUrl
                ])
                ask_to_name = ask_to.data.get(Studio.Field.name)
                ask_to_avatar_url = ask_to.data.get(Studio.Field.avatarUrl)
                ask_to_type = 2
            except NotFound:
                pass

        problems.append({
            Problem.Field._id: problem.get(Problem.Field._id),
            Problem.Field.askTo: problem.get(Problem.Field.askTo),
            'askToName': ask_to_name,
            'askToAvatarUrl': ask_to_avatar_url,
            'askToType': ask_to_type,
            Problem.Field.commentNum: problem.get(Problem.Field.commentNum),
            Problem.Field.content: problem.get(Problem.Field.content),
            Problem.Field.image: problem.get(Problem.Field.image),
            'isZan': is_zan,
            Problem.Field.zan: problem.get(Problem.Field.zan),
            Problem.Field.tag: problem.get(Problem.Field.tag),
            Problem.Field.viewNum: problem.get(Problem.Field.viewNum),
            Problem.Field.answerNum: problem.get(Problem.Field.answerNum),
            Problem.Field.timestamp: problem.get(Problem.Field.timestamp),
            Problem.Field.userId: problem.get(Problem.Field.userId),
            User.Field.name: user.data.get(User.Field.name),
            User.Field.avatarUrl: user.data.get(User.Field.avatarUrl)
        })

    return jsonify(stat=1, problems=problems)
